
from crud.mindMap import create_mind_map, get_mind_maps_by_material, update_mind_map
from schemas.material import MaterialContent
from schemas.mindMap import MindMapCreate, MindMapUpdate
from utils.utils import deduplicate_dict_list
from utils.auth import get_current_user
from models.models import LearnUser
from crud.page_record import get_material_mind_map_status, update_material_mind_map_status
from sqlalchemy.orm import Session
from database import SessionLocal
from utils.log_manager import app_logger
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel
from core.agent.mindModel import MindModel, MarkdownToJsMind, merge_trees  # 导入思维导图相关类
from config import settings
from crud.material import get_material_content
import json

router = APIRouter(prefix='/agent')
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

api_key = settings.api_key
api_base = settings.api_base
mind_model = MindModel(api_key, api_base)  # 创建思维导图模型实例
markdown_to_js_mind = MarkdownToJsMind()  # 创建Markdown转思维导图实例

# 定义思维导图相关请求体模型
class MindMapRequest(BaseModel):
    material_id: int

@router.get("/mindmap")
async def get_mindmap(material_id: int, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 获取指定材料的最新思维导图
        user_mind_maps = get_mind_maps_by_material(db, material_id, current_user.id)
        
        if not user_mind_maps:
            # 如果没有找到思维导图，返回空结构
            return {"meta": {"name": "思维导图"}, "format": "node_tree", "data": {"id": "root", "topic": "根节点", "children": []}}
        
        # 按版本号降序排序并获取最新版本
        latest_mind_map = sorted(user_mind_maps, key=lambda mm: mm.version, reverse=True)[0]
        
        # 返回存储的思维导图内容
        return json.loads(latest_mind_map.mind_map_json)
    except Exception as e:
        app_logger.error(f"获取思维导图失败: {e}")
        raise HTTPException(status_code=500, detail=str("获取思维导图失败"))

@router.get("/mindmap/newRecords")
async def get_new_records(material_id: int, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 获取未用于生成思维导图的知识点
        new_records = get_material_mind_map_status(db, material_id, current_user.id)
        # 返回这些知识点的页码
        page_numbers = [record.page_number for record in new_records]
        return page_numbers
    except Exception as e:
        app_logger.error(f"获取新增阅读记录失败: {e}")
        raise HTTPException(status_code=500, detail=str("获取新增阅读记录失败"))

@router.get("/mindmap/checkNewRecords")
async def check_new_records(material_id: int, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 检查是否有新增未用于思维导图生成的记录
        new_records = get_material_mind_map_status(db, material_id, current_user.id)
        has_new_records = len(new_records) > 0
        page_numbers = [record.page_number for record in new_records]
        return {"has_new_records": has_new_records, "page_numbers": page_numbers}
    except Exception as e:
        app_logger.error(f"检查新增阅读记录失败: {e}")
        raise HTTPException(status_code=500, detail=str("检查新增阅读记录失败"))

@router.post("/mindmap/generate")
async def generate_mindmap(request: MindMapRequest, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 获取未用于生成思维导图的知识点
        new_records = get_material_mind_map_status(db, request.material_id, current_user.id)
        
        if not new_records:
            raise HTTPException(status_code=404, detail=str("没有新增阅读记录，无法生成思维导图"))
        
        # 获取这些页的内容
        new_records =  deduplicate_dict_list([{"material_id":record.material_id,"page_number":record.page_number} for record in new_records])
        materials = [MaterialContent(material_id=record["material_id"], page_number=record["page_number"]) for record in new_records]
        material_content = get_material_content(db, materials)
        
        if not material_content:
            raise HTTPException(status_code=404, detail=str("未找到材料内容"))
        
        # 生成思维导图的Markdown
        md_content = mind_model.generate_md(material_content)
        
        # 转换为思维导图JSON
        js_mind = markdown_to_js_mind.build_tree(md_content)
        
        # 创建思维导图记录
        mind_map_data = MindMapCreate(
            material_id=request.material_id,
            user_id=current_user.id,
            mind_map_json=json.dumps(js_mind),
            version=1
        )
        
        create_mind_map(db, mind_map_data)
        
        # 更新知识点状态为已用于生成思维导图
        update_material_mind_map_status(db, request.material_id, current_user.id)
        
        return js_mind  
    except Exception as e:
        app_logger.error(f"生成思维导图失败: {e}")
        raise HTTPException(status_code=500, detail=str("生成思维导图失败"))

@router.post("/mindmap/update")
async def update_mindmap(request: MindMapRequest, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 获取未用于生成思维导图的新知识点
        new_records = get_material_mind_map_status(db, request.material_id, current_user.id)
        
        if not new_records:
            raise HTTPException(status_code=404, detail=str("没有新增阅读记录，无法更新思维导图"))
        
        # 获取该材料的所有思维导图
        existing_mind_maps = get_mind_maps_by_material(db, request.material_id, current_user.id)
        
        if not existing_mind_maps:
            # 如果没有现有思维导图，则直接生成新的
            return await generate_mindmap(request, current_user, db)
        
        # 获取最新版本的思维导图
        latest_mind_map = sorted(existing_mind_maps, key=lambda mm: mm.version, reverse=True)[0]
        old_mind_map = json.loads(latest_mind_map.mind_map_json)
        
        # 获取新记录内容
        new_records =  deduplicate_dict_list([{"material_id":record.material_id,"page_number":record.page_number} for record in new_records])
        materials = [MaterialContent(material_id=record["material_id"], page_number=record["page_number"]) for record in new_records]
        material_content = get_material_content(db, materials)
        
        if not material_content:
            raise HTTPException(status_code=404, detail=str("未找到新增材料内容"))
        
        # 生成新部分的思维导图
        md_content = mind_model.generate_md(material_content)
        new_mind_map = markdown_to_js_mind.build_tree(md_content)
        
        # 合并思维导图
        merged_mind_map = merge_trees(old_mind_map, new_mind_map)
        
        # 更新思维导图
        mind_map_update = MindMapUpdate(
            mind_map_json=json.dumps(merged_mind_map)
        )
        
        update_mind_map(db, latest_mind_map.id, mind_map_update)
        
        # 更新知识点状态为已用于生成思维导图
        update_material_mind_map_status(db, request.material_id, current_user.id)
        
        return merged_mind_map
    except Exception as e:
        app_logger.error(f"更新思维导图失败: {e}")
        raise HTTPException(status_code=500, detail=str("更新思维导图失败"))
 
# 定义思维导图保存请求体模型
class MindMapSaveRequest(BaseModel):
    material_id: int
    mindmap_json: dict

@router.post("/mindmap/save")
async def save_mindmap(request: MindMapSaveRequest, current_user: LearnUser = Depends(get_current_user), db: Session = Depends(get_db)):
    try:
        # 获取该材料的所有思维导图
        existing_mind_maps = get_mind_maps_by_material(db, request.material_id, current_user.id)
        
        if not existing_mind_maps:
            # 如果没有现有思维导图，则创建新的
            mind_map_data = MindMapCreate(
                material_id=request.material_id,
                user_id=current_user.id,
                mind_map_json=json.dumps(request.mindmap_json),
                version=1
            )
            create_mind_map(db, mind_map_data)
        else:
            # 获取最新版本的思维导图
            latest_mind_map = sorted(existing_mind_maps, key=lambda mm: mm.version, reverse=True)[0]
            
            # 更新思维导图
            mind_map_update = MindMapUpdate(
                mind_map_json=json.dumps(request.mindmap_json)
            )
            
            update_mind_map(db, latest_mind_map.id, mind_map_update)
        
        return {"status": "success", "message": "思维导图保存成功"}
    except Exception as e:
        app_logger.error(f"保存思维导图失败: {e}")
        raise HTTPException(status_code=500, detail=str("保存思维导图失败"))
        
